1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package com.google.common.io;
18
19 import com.google.common.base.Charsets;
20
21 import java.io.ByteArrayInputStream;
22 import java.io.ByteArrayOutputStream;
23 import java.io.EOFException;
24 import java.io.FilterInputStream;
25 import java.io.IOException;
26 import java.io.InputStream;
27 import java.io.OutputStream;
28 import java.nio.channels.Channels;
29 import java.nio.channels.ReadableByteChannel;
30 import java.nio.channels.WritableByteChannel;
31 import java.util.Arrays;
32
33
34
35
36
37
38 public class ByteStreamsTest extends IoTestCase {
39
40 public void testCopyChannel() throws IOException {
41 byte[] expected = newPreFilledByteArray(100);
42 ByteArrayOutputStream out = new ByteArrayOutputStream();
43 WritableByteChannel outChannel = Channels.newChannel(out);
44
45 ReadableByteChannel inChannel =
46 Channels.newChannel(new ByteArrayInputStream(expected));
47 ByteStreams.copy(inChannel, outChannel);
48 assertEquals(expected, out.toByteArray());
49 }
50
51 public void testReadFully() throws IOException {
52 byte[] b = new byte[10];
53
54 try {
55 ByteStreams.readFully(newTestStream(10), null, 0, 10);
56 fail("expected exception");
57 } catch (NullPointerException e) {
58 }
59
60 try {
61 ByteStreams.readFully(null, b, 0, 10);
62 fail("expected exception");
63 } catch (NullPointerException e) {
64 }
65
66 try {
67 ByteStreams.readFully(newTestStream(10), b, -1, 10);
68 fail("expected exception");
69 } catch (IndexOutOfBoundsException e) {
70 }
71
72 try {
73 ByteStreams.readFully(newTestStream(10), b, 0, -1);
74 fail("expected exception");
75 } catch (IndexOutOfBoundsException e) {
76 }
77
78 try {
79 ByteStreams.readFully(newTestStream(10), b, 0, -1);
80 fail("expected exception");
81 } catch (IndexOutOfBoundsException e) {
82 }
83
84 try {
85 ByteStreams.readFully(newTestStream(10), b, 2, 10);
86 fail("expected exception");
87 } catch (IndexOutOfBoundsException e) {
88 }
89
90 try {
91 ByteStreams.readFully(newTestStream(5), b, 0, 10);
92 fail("expected exception");
93 } catch (EOFException e) {
94 }
95
96 Arrays.fill(b, (byte) 0);
97 ByteStreams.readFully(newTestStream(10), b, 0, 0);
98 assertEquals(new byte[10], b);
99
100 Arrays.fill(b, (byte) 0);
101 ByteStreams.readFully(newTestStream(10), b, 0, 10);
102 assertEquals(newPreFilledByteArray(10), b);
103
104 Arrays.fill(b, (byte) 0);
105 ByteStreams.readFully(newTestStream(10), b, 0, 5);
106 assertEquals(new byte[]{0, 1, 2, 3, 4, 0, 0, 0, 0, 0}, b);
107 }
108
109 public void testSkipFully() throws IOException {
110 byte[] bytes = newPreFilledByteArray(100);
111 skipHelper(0, 0, new ByteArrayInputStream(bytes));
112 skipHelper(50, 50, new ByteArrayInputStream(bytes));
113 skipHelper(50, 50, new SlowSkipper(new ByteArrayInputStream(bytes), 1));
114 skipHelper(50, 50, new SlowSkipper(new ByteArrayInputStream(bytes), 0));
115 skipHelper(100, -1, new ByteArrayInputStream(bytes));
116 try {
117 skipHelper(101, 0, new ByteArrayInputStream(bytes));
118 fail("expected exception");
119 } catch (EOFException e) {
120 }
121 }
122
123 private static void skipHelper(long n, int expect, InputStream in)
124 throws IOException {
125 ByteStreams.skipFully(in, n);
126 assertEquals(expect, in.read());
127 in.close();
128 }
129
130 private static final byte[] bytes =
131 new byte[] { 0x12, 0x34, 0x56, 0x78, 0x76, 0x54, 0x32, 0x10 };
132
133 public void testNewDataInput_empty() {
134 byte[] b = new byte[0];
135 ByteArrayDataInput in = ByteStreams.newDataInput(b);
136 try {
137 in.readInt();
138 fail("expected exception");
139 } catch (IllegalStateException expected) {
140 }
141 }
142
143 public void testNewDataInput_normal() {
144 ByteArrayDataInput in = ByteStreams.newDataInput(bytes);
145 assertEquals(0x12345678, in.readInt());
146 assertEquals(0x76543210, in.readInt());
147 try {
148 in.readInt();
149 fail("expected exception");
150 } catch (IllegalStateException expected) {
151 }
152 }
153
154 public void testNewDataInput_readFully() {
155 ByteArrayDataInput in = ByteStreams.newDataInput(bytes);
156 byte[] actual = new byte[bytes.length];
157 in.readFully(actual);
158 assertEquals(bytes, actual);
159 }
160
161 public void testNewDataInput_readFullyAndThenSome() {
162 ByteArrayDataInput in = ByteStreams.newDataInput(bytes);
163 byte[] actual = new byte[bytes.length * 2];
164 try {
165 in.readFully(actual);
166 fail("expected exception");
167 } catch (IllegalStateException ex) {
168 assertTrue(ex.getCause() instanceof EOFException);
169 }
170 }
171
172 public void testNewDataInput_readFullyWithOffset() {
173 ByteArrayDataInput in = ByteStreams.newDataInput(bytes);
174 byte[] actual = new byte[4];
175 in.readFully(actual, 2, 2);
176 assertEquals(0, actual[0]);
177 assertEquals(0, actual[1]);
178 assertEquals(bytes[0], actual[2]);
179 assertEquals(bytes[1], actual[3]);
180 }
181
182 public void testNewDataInput_readLine() {
183 ByteArrayDataInput in = ByteStreams.newDataInput(
184 "This is a line\r\nThis too\rand this\nand also this".getBytes(Charsets.UTF_8));
185 assertEquals("This is a line", in.readLine());
186 assertEquals("This too", in.readLine());
187 assertEquals("and this", in.readLine());
188 assertEquals("and also this", in.readLine());
189 }
190
191 public void testNewDataInput_readFloat() {
192 byte[] data = {0x12, 0x34, 0x56, 0x78, 0x76, 0x54, 0x32, 0x10};
193 ByteArrayDataInput in = ByteStreams.newDataInput(data);
194 assertEquals(Float.intBitsToFloat(0x12345678), in.readFloat(), 0.0);
195 assertEquals(Float.intBitsToFloat(0x76543210), in.readFloat(), 0.0);
196 }
197
198 public void testNewDataInput_readDouble() {
199 byte[] data = {0x12, 0x34, 0x56, 0x78, 0x76, 0x54, 0x32, 0x10};
200 ByteArrayDataInput in = ByteStreams.newDataInput(data);
201 assertEquals(Double.longBitsToDouble(0x1234567876543210L), in.readDouble(), 0.0);
202 }
203
204 public void testNewDataInput_readUTF() {
205 byte[] data = new byte[17];
206 data[1] = 15;
207 System.arraycopy("Kilroy was here".getBytes(Charsets.UTF_8), 0, data, 2, 15);
208 ByteArrayDataInput in = ByteStreams.newDataInput(data);
209 assertEquals("Kilroy was here", in.readUTF());
210 }
211
212 public void testNewDataInput_readChar() {
213 byte[] data = "qed".getBytes(Charsets.UTF_16BE);
214 ByteArrayDataInput in = ByteStreams.newDataInput(data);
215 assertEquals('q', in.readChar());
216 assertEquals('e', in.readChar());
217 assertEquals('d', in.readChar());
218 }
219
220 public void testNewDataInput_readUnsignedShort() {
221 byte[] data = {0, 0, 0, 1, (byte) 0xFF, (byte) 0xFF, 0x12, 0x34};
222 ByteArrayDataInput in = ByteStreams.newDataInput(data);
223 assertEquals(0, in.readUnsignedShort());
224 assertEquals(1, in.readUnsignedShort());
225 assertEquals(65535, in.readUnsignedShort());
226 assertEquals(0x1234, in.readUnsignedShort());
227 }
228
229 public void testNewDataInput_readLong() {
230 byte[] data = {0x12, 0x34, 0x56, 0x78, 0x76, 0x54, 0x32, 0x10};
231 ByteArrayDataInput in = ByteStreams.newDataInput(data);
232 assertEquals(0x1234567876543210L, in.readLong());
233 }
234
235 public void testNewDataInput_readBoolean() {
236 ByteArrayDataInput in = ByteStreams.newDataInput(bytes);
237 assertTrue(in.readBoolean());
238 }
239
240 public void testNewDataInput_readByte() {
241 ByteArrayDataInput in = ByteStreams.newDataInput(bytes);
242 for (int i = 0; i < bytes.length; i++) {
243 assertEquals(bytes[i], in.readByte());
244 }
245 try {
246 in.readByte();
247 fail("expected exception");
248 } catch (IllegalStateException ex) {
249 assertTrue(ex.getCause() instanceof EOFException);
250 }
251 }
252
253 public void testNewDataInput_readUnsignedByte() {
254 ByteArrayDataInput in = ByteStreams.newDataInput(bytes);
255 for (int i = 0; i < bytes.length; i++) {
256 assertEquals(bytes[i], in.readUnsignedByte());
257 }
258 try {
259 in.readUnsignedByte();
260 fail("expected exception");
261 } catch (IllegalStateException ex) {
262 assertTrue(ex.getCause() instanceof EOFException);
263 }
264 }
265
266 public void testNewDataInput_offset() {
267 ByteArrayDataInput in = ByteStreams.newDataInput(bytes, 2);
268 assertEquals(0x56787654, in.readInt());
269 try {
270 in.readInt();
271 fail("expected exception");
272 } catch (IllegalStateException expected) {
273 }
274 }
275
276 public void testNewDataInput_skip() {
277 ByteArrayDataInput in = ByteStreams.newDataInput(new byte[2]);
278 assertEquals(2, in.skipBytes(2));
279 assertEquals(0, in.skipBytes(1));
280 }
281
282 public void testNewDataInput_BAIS() {
283 ByteArrayInputStream bais = new ByteArrayInputStream(new byte[] {0x12, 0x34, 0x56, 0x78});
284 ByteArrayDataInput in = ByteStreams.newDataInput(bais);
285 assertEquals(0x12345678, in.readInt());
286 }
287
288 public void testNewDataOutput_empty() {
289 ByteArrayDataOutput out = ByteStreams.newDataOutput();
290 assertEquals(0, out.toByteArray().length);
291 }
292
293 public void testNewDataOutput_writeInt() {
294 ByteArrayDataOutput out = ByteStreams.newDataOutput();
295 out.writeInt(0x12345678);
296 out.writeInt(0x76543210);
297 assertEquals(bytes, out.toByteArray());
298 }
299
300 public void testNewDataOutput_sized() {
301 ByteArrayDataOutput out = ByteStreams.newDataOutput(4);
302 out.writeInt(0x12345678);
303 out.writeInt(0x76543210);
304 assertEquals(bytes, out.toByteArray());
305 }
306
307 public void testNewDataOutput_writeLong() {
308 ByteArrayDataOutput out = ByteStreams.newDataOutput();
309 out.writeLong(0x1234567876543210L);
310 assertEquals(bytes, out.toByteArray());
311 }
312
313 public void testNewDataOutput_writeByteArray() {
314 ByteArrayDataOutput out = ByteStreams.newDataOutput();
315 out.write(bytes);
316 assertEquals(bytes, out.toByteArray());
317 }
318
319 public void testNewDataOutput_writeByte() {
320 ByteArrayDataOutput out = ByteStreams.newDataOutput();
321 out.write(0x12);
322 out.writeByte(0x34);
323 assertEquals(new byte[] {0x12, 0x34}, out.toByteArray());
324 }
325
326 public void testNewDataOutput_writeByteOffset() {
327 ByteArrayDataOutput out = ByteStreams.newDataOutput();
328 out.write(bytes, 4, 2);
329 byte[] expected = {bytes[4], bytes[5]};
330 assertEquals(expected, out.toByteArray());
331 }
332
333 public void testNewDataOutput_writeBoolean() {
334 ByteArrayDataOutput out = ByteStreams.newDataOutput();
335 out.writeBoolean(true);
336 out.writeBoolean(false);
337 byte[] expected = {(byte) 1, (byte) 0};
338 assertEquals(expected, out.toByteArray());
339 }
340
341 public void testNewDataOutput_writeChar() {
342 ByteArrayDataOutput out = ByteStreams.newDataOutput();
343 out.writeChar('a');
344 assertEquals(new byte[] {0, 97}, out.toByteArray());
345 }
346
347 public void testNewDataOutput_writeChars() {
348 ByteArrayDataOutput out = ByteStreams.newDataOutput();
349 out.writeChars("r\u00C9sum\u00C9");
350
351 byte[] expected = Arrays.copyOfRange("r\u00C9sum\u00C9".getBytes(Charsets.UTF_16), 2, 14);
352 assertEquals(expected, out.toByteArray());
353 }
354
355 public void testNewDataOutput_writeUTF() {
356 ByteArrayDataOutput out = ByteStreams.newDataOutput();
357 out.writeUTF("r\u00C9sum\u00C9");
358 byte[] expected ="r\u00C9sum\u00C9".getBytes(Charsets.UTF_8);
359 byte[] actual = out.toByteArray();
360
361 assertEquals(0, actual[0]);
362 assertEquals(expected.length, actual[1]);
363 assertEquals(expected, Arrays.copyOfRange(actual, 2, actual.length));
364 }
365
366 public void testNewDataOutput_writeShort() {
367 ByteArrayDataOutput out = ByteStreams.newDataOutput();
368 out.writeShort(0x1234);
369 assertEquals(new byte[] {0x12, 0x34}, out.toByteArray());
370 }
371
372 public void testNewDataOutput_writeDouble() {
373 ByteArrayDataOutput out = ByteStreams.newDataOutput();
374 out.writeDouble(Double.longBitsToDouble(0x1234567876543210L));
375 assertEquals(bytes, out.toByteArray());
376 }
377
378 public void testNewDataOutput_writeFloat() {
379 ByteArrayDataOutput out = ByteStreams.newDataOutput();
380 out.writeFloat(Float.intBitsToFloat(0x12345678));
381 out.writeFloat(Float.intBitsToFloat(0x76543210));
382 assertEquals(bytes, out.toByteArray());
383 }
384
385 public void testNewDataOutput_BAOS() {
386 ByteArrayOutputStream baos = new ByteArrayOutputStream();
387 ByteArrayDataOutput out = ByteStreams.newDataOutput(baos);
388 out.writeInt(0x12345678);
389 assertEquals(4, baos.size());
390 assertEquals(new byte[] {0x12, 0x34, 0x56, 0x78}, baos.toByteArray());
391 }
392
393 public void testToByteArray_withSize_givenCorrectSize() throws IOException {
394 InputStream in = newTestStream(100);
395 byte[] b = ByteStreams.toByteArray(in, 100);
396 assertEquals(100, b.length);
397 }
398
399 public void testToByteArray_withSize_givenSmallerSize() throws IOException {
400 InputStream in = newTestStream(100);
401 byte[] b = ByteStreams.toByteArray(in, 80);
402 assertEquals(100, b.length);
403 }
404
405 public void testToByteArray_withSize_givenLargerSize() throws IOException {
406 InputStream in = newTestStream(100);
407 byte[] b = ByteStreams.toByteArray(in, 120);
408 assertEquals(100, b.length);
409 }
410
411 public void testToByteArray_withSize_givenSizeZero() throws IOException {
412 InputStream in = newTestStream(100);
413 byte[] b = ByteStreams.toByteArray(in, 0);
414 assertEquals(100, b.length);
415 }
416
417 private static InputStream newTestStream(int n) {
418 return new ByteArrayInputStream(newPreFilledByteArray(n));
419 }
420
421
422 private static class SlowSkipper extends FilterInputStream {
423 private final long max;
424
425 public SlowSkipper(InputStream in, long max) {
426 super(in);
427 this.max = max;
428 }
429
430 @Override public long skip(long n) throws IOException {
431 return super.skip(Math.min(max, n));
432 }
433 }
434
435 public void testReadBytes() throws IOException {
436 final byte[] array = newPreFilledByteArray(1000);
437 assertEquals(array, ByteStreams.readBytes(
438 new ByteArrayInputStream(array), new TestByteProcessor()));
439 }
440
441 private class TestByteProcessor implements ByteProcessor<byte[]> {
442 private final ByteArrayOutputStream out = new ByteArrayOutputStream();
443
444 @Override
445 public boolean processBytes(byte[] buf, int off, int len)
446 throws IOException {
447 out.write(buf, off, len);
448 return true;
449 }
450
451 @Override
452 public byte[] getResult() {
453 return out.toByteArray();
454 }
455 }
456
457 public void testByteProcessorStopEarly() throws IOException {
458 byte[] array = newPreFilledByteArray(6000);
459 assertEquals((Integer) 42,
460 ByteStreams.readBytes(new ByteArrayInputStream(array),
461 new ByteProcessor<Integer>() {
462 @Override
463 public boolean processBytes(byte[] buf, int off, int len) {
464 assertEquals(
465 copyOfRange(buf, off, off + len),
466 newPreFilledByteArray(4096));
467 return false;
468 }
469
470 @Override
471 public Integer getResult() {
472 return 42;
473 }
474 }));
475 }
476
477 public void testNullOutputStream() throws Exception {
478
479 OutputStream nos = ByteStreams.nullOutputStream();
480
481 nos.write('n');
482 String test = "Test string for NullOutputStream";
483 nos.write(test.getBytes());
484 nos.write(test.getBytes(), 2, 10);
485
486 assertSame(ByteStreams.nullOutputStream(), ByteStreams.nullOutputStream());
487 }
488
489 public void testLimit() throws Exception {
490 byte[] big = newPreFilledByteArray(5);
491 InputStream bin = new ByteArrayInputStream(big);
492 InputStream lin = ByteStreams.limit(bin, 2);
493
494
495 lin.mark(2);
496 assertEquals(2, lin.available());
497 int read = lin.read();
498 assertEquals(big[0], read);
499 assertEquals(1, lin.available());
500 read = lin.read();
501 assertEquals(big[1], read);
502 assertEquals(0, lin.available());
503 read = lin.read();
504 assertEquals(-1, read);
505
506 lin.reset();
507 byte[] small = new byte[5];
508 read = lin.read(small);
509 assertEquals(2, read);
510 assertEquals(big[0], small[0]);
511 assertEquals(big[1], small[1]);
512
513 lin.reset();
514 read = lin.read(small, 2, 3);
515 assertEquals(2, read);
516 assertEquals(big[0], small[2]);
517 assertEquals(big[1], small[3]);
518 }
519
520 public void testLimit_mark() throws Exception {
521 byte[] big = newPreFilledByteArray(5);
522 InputStream bin = new ByteArrayInputStream(big);
523 InputStream lin = ByteStreams.limit(bin, 2);
524
525 int read = lin.read();
526 assertEquals(big[0], read);
527 lin.mark(2);
528
529 read = lin.read();
530 assertEquals(big[1], read);
531 read = lin.read();
532 assertEquals(-1, read);
533
534 lin.reset();
535 read = lin.read();
536 assertEquals(big[1], read);
537 read = lin.read();
538 assertEquals(-1, read);
539 }
540
541 public void testLimit_skip() throws Exception {
542 byte[] big = newPreFilledByteArray(5);
543 InputStream bin = new ByteArrayInputStream(big);
544 InputStream lin = ByteStreams.limit(bin, 2);
545
546
547 lin.mark(2);
548 assertEquals(2, lin.available());
549 lin.skip(1);
550 assertEquals(1, lin.available());
551
552 lin.reset();
553 assertEquals(2, lin.available());
554 lin.skip(3);
555 assertEquals(0, lin.available());
556 }
557
558 public void testLimit_markNotSet() {
559 byte[] big = newPreFilledByteArray(5);
560 InputStream bin = new ByteArrayInputStream(big);
561 InputStream lin = ByteStreams.limit(bin, 2);
562
563 try {
564 lin.reset();
565 fail();
566 } catch (IOException expected) {
567 assertEquals("Mark not set", expected.getMessage());
568 }
569 }
570
571 public void testLimit_markNotSupported() {
572 InputStream lin = ByteStreams.limit(new UnmarkableInputStream(), 2);
573
574 try {
575 lin.reset();
576 fail();
577 } catch (IOException expected) {
578 assertEquals("Mark not supported", expected.getMessage());
579 }
580 }
581
582 private static class UnmarkableInputStream extends InputStream {
583 @Override
584 public int read() throws IOException {
585 return 0;
586 }
587
588 @Override
589 public boolean markSupported() {
590 return false;
591 }
592 }
593
594 private static byte[] copyOfRange(byte[] in, int from, int to) {
595 byte[] out = new byte[to - from];
596 for (int i = 0; i < to - from; i++) {
597 out[i] = in[from + i];
598 }
599 return out;
600 }
601
602 private static void assertEquals(byte[] expected, byte[] actual) {
603 assertTrue(Arrays.equals(expected, actual));
604 }
605 }